home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / darts06.zip / ITEMS.QC < prev    next >
Text File  |  1996-08-28  |  29KB  |  1,349 lines

  1. void() W_SetCurrentAmmo;
  2. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  3. BE .8 .3 .4 IN COLOR */
  4.  
  5.  
  6. void() SUB_regen =
  7. {
  8.     self.model = self.mdl;        // restore original model
  9.     self.solid = SOLID_TRIGGER;    // allow it to be touched again
  10.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  11.     setorigin (self, self.origin);
  12. };
  13.  
  14.  
  15.  
  16. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  17. prints a warning message when spawned
  18. */
  19. void() noclass =
  20. {
  21.     dprint ("noclass spawned at");
  22.     dprint (vtos(self.origin));
  23.     dprint ("\n");
  24.     remove (self);
  25. };
  26.  
  27.  
  28.  
  29. /*
  30. ============
  31. PlaceItem
  32.  
  33. plants the object on the floor
  34. ============
  35. */
  36. void() PlaceItem =
  37. {
  38.     local float    oldz;
  39.  
  40.     self.mdl = self.model;        // so it can be restored on respawn
  41.     self.flags = FL_ITEM;        // make extra wide
  42.     self.solid = SOLID_TRIGGER;
  43.     self.movetype = MOVETYPE_TOSS;    
  44.     self.velocity = '0 0 0';
  45.     self.origin_z = self.origin_z + 6;
  46.     oldz = self.origin_z;
  47.     if (!droptofloor())
  48.     {
  49.         dprint ("Bonus item fell out of level at ");
  50.         dprint (vtos(self.origin));
  51.         dprint ("\n");
  52.         remove(self);
  53.         return;
  54.     }
  55. };
  56.  
  57. /*
  58. ============
  59. StartItem
  60.  
  61. Sets the clipping size and plants the object on the floor
  62. ============
  63. */
  64. void() StartItem =
  65. {
  66.     self.nextthink = time + 0.2;    // items start after other solids
  67.     self.think = PlaceItem;
  68. };
  69.  
  70. /*
  71. =========================================================================
  72.  
  73. HEALTH BOX
  74.  
  75. =========================================================================
  76. */
  77. //
  78. // T_Heal: add health to an entity, limiting health to max_health
  79. // "ignore" will ignore max_health limit
  80. //
  81. float (entity e, float healamount, float ignore) T_Heal =
  82. {
  83.     if (e.health <= 0)
  84.         return 0;
  85.     if ((!ignore) && (e.health >= other.max_health))
  86.         return 0;
  87.     healamount = ceil(healamount);
  88.  
  89.     e.health = e.health + healamount;
  90.     if ((!ignore) && (e.health >= other.max_health))
  91.         e.health = other.max_health;
  92.         
  93.     if (e.health > 250)
  94.         e.health = 250;
  95.     return 1;
  96. };
  97.  
  98. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  99. Health box. Normally gives 25 points.
  100. Rotten box heals 5-10 points,
  101. megahealth will add 100 health, then 
  102. rot you down to your maximum health limit, 
  103. one point per second.
  104. */
  105.  
  106. float    H_ROTTEN = 1;
  107. float    H_MEGA = 2;
  108. .float    healamount, healtype;
  109. void() health_touch;
  110. void() item_megahealth_rot;
  111.  
  112. void() item_health =
  113. {    
  114.     self.touch = health_touch;
  115.  
  116.     if (self.spawnflags & H_ROTTEN)
  117.     {
  118.         precache_model("maps/b_bh10.bsp");
  119.  
  120.         precache_sound("items/r_item1.wav");
  121.         setmodel(self, "maps/b_bh10.bsp");
  122.         self.noise = "items/r_item1.wav";
  123.         self.healamount = 15;
  124.         self.healtype = 0;
  125.     }
  126.     else
  127.     if (self.spawnflags & H_MEGA)
  128.     {
  129.         precache_model("maps/b_bh100.bsp");
  130.         precache_sound("items/r_item2.wav");
  131.         setmodel(self, "maps/b_bh100.bsp");
  132.         self.noise = "items/r_item2.wav";
  133.         self.healamount = 100;
  134.         self.healtype = 2;
  135.     }
  136.     else
  137.     {
  138.         precache_model("maps/b_bh25.bsp");
  139.         precache_sound("items/health1.wav");
  140.         setmodel(self, "maps/b_bh25.bsp");
  141.         self.noise = "items/health1.wav";
  142.         self.healamount = 25;
  143.         self.healtype = 1;
  144.     }
  145.     setsize (self, '0 0 0', '32 32 56');
  146.     StartItem ();
  147. };
  148.  
  149.  
  150. void() health_touch =
  151. {
  152.     local    float amount;
  153.     local    string    s;
  154.     
  155.     if (other.classname != "player")
  156.         return;
  157.  
  158.         if (other.darts > 1)
  159.          other.darts = other.darts - 1;
  160.  
  161.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  162.     {
  163.         if (other.health >= 250)
  164.             return;
  165.         if (!T_Heal(other, self.healamount, 1))
  166.             return;
  167.     }
  168.     else
  169.     {
  170.         if (!T_Heal(other, self.healamount, 0))
  171.             return;
  172.     }
  173.     
  174.     sprint(other, "You receive ");
  175.     s = ftos(self.healamount);
  176.     sprint(other, s);
  177.     sprint(other, " health\n");
  178.     
  179. // health touch sound
  180.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  181.  
  182.     stuffcmd (other, "bf\n");
  183.     
  184.     self.model = string_null;
  185.     self.solid = SOLID_NOT;
  186.  
  187.     // Megahealth = rot down the player's super health
  188.     if (self.healtype == 2)
  189.     {
  190.         other.items = other.items | IT_SUPERHEALTH;
  191.         self.nextthink = time + 5;
  192.         self.think = item_megahealth_rot;
  193.         self.owner = other;
  194.     }
  195.     else
  196.     {
  197.         if (deathmatch != 2)        // deathmatch 2 is the silly old rules
  198.         {
  199.             if (deathmatch)
  200.                 self.nextthink = time + 20;
  201.             self.think = SUB_regen;
  202.         }
  203.     }
  204.     
  205.     activator = other;
  206.     SUB_UseTargets();                // fire all targets / killtargets
  207. };    
  208.  
  209. void() item_megahealth_rot =
  210. {
  211.     other = self.owner;
  212.     
  213.     if (other.health > other.max_health)
  214.     {
  215.         other.health = other.health - 1;
  216.         self.nextthink = time + 1;
  217.         return;
  218.     }
  219.  
  220. // it is possible for a player to die and respawn between rots, so don't
  221. // just blindly subtract the flag off
  222.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  223.     
  224.     if (deathmatch == 1)    // deathmatch 2 is silly old rules
  225.     {
  226.         self.nextthink = time + 20;
  227.         self.think = SUB_regen;
  228.     }
  229. };
  230.  
  231. /*
  232. ===============================================================================
  233.  
  234. ARMOR
  235.  
  236. ===============================================================================
  237. */
  238.  
  239. void() armor_touch;
  240.  
  241. void() armor_touch =
  242. {
  243.     local    float    type, value, bit;
  244.     
  245.     if (other.health <= 0)
  246.         return;
  247.     if (other.classname != "player")
  248.         return;
  249.  
  250.     if (self.classname == "item_armor1")
  251.     {
  252.         type = 0.3;
  253.         value = 100;
  254.         bit = IT_ARMOR1;
  255.     }
  256.     if (self.classname == "item_armor2")
  257.     {
  258.         type = 0.6;
  259.         value = 150;
  260.         bit = IT_ARMOR2;
  261.     }
  262.     if (self.classname == "item_armorInv")
  263.     {
  264.         type = 0.8;
  265.         value = 200;
  266.         bit = IT_ARMOR3;
  267.     }
  268.     if (other.armortype*other.armorvalue >= type*value)
  269.         return;
  270.         
  271.     other.armortype = type;
  272.     other.armorvalue = value;
  273.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  274.  
  275.     self.solid = SOLID_NOT;
  276.     self.model = string_null;
  277.     if (deathmatch == 1)
  278.         self.nextthink = time + 20;
  279.     self.think = SUB_regen;
  280.  
  281.     sprint(other, "You got armor\n");
  282. // armor touch sound
  283.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  284.     stuffcmd (other, "bf\n");
  285.     
  286.     activator = other;
  287.     SUB_UseTargets();                // fire all targets / killtargets
  288. };
  289.  
  290.  
  291. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  292. */
  293.  
  294. void() item_armor1 =
  295. {
  296.     self.touch = armor_touch;
  297.     precache_model ("progs/armor.mdl");
  298.     setmodel (self, "progs/armor.mdl");
  299.     self.skin = 0;
  300.     setsize (self, '-16 -16 0', '16 16 56');
  301.     StartItem ();
  302. };
  303.  
  304. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  305. */
  306.  
  307. void() item_armor2 =
  308. {
  309.     self.touch = armor_touch;
  310.     precache_model ("progs/armor.mdl");
  311.     setmodel (self, "progs/armor.mdl");
  312.     self.skin = 1;
  313.     setsize (self, '-16 -16 0', '16 16 56');
  314.     StartItem ();
  315. };
  316.  
  317. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  318. */
  319.  
  320. void() item_armorInv =
  321. {
  322.     self.touch = armor_touch;
  323.     precache_model ("progs/armor.mdl");
  324.     setmodel (self, "progs/armor.mdl");
  325.     self.skin = 2;
  326.     setsize (self, '-16 -16 0', '16 16 56');
  327.     StartItem ();
  328. };
  329.  
  330. /*
  331. ===============================================================================
  332.  
  333. WEAPONS
  334.  
  335. ===============================================================================
  336. */
  337.  
  338. void() bound_other_ammo =
  339. {
  340.     if (other.ammo_shells > 100)
  341.         other.ammo_shells = 100;
  342.     if (other.ammo_nails > 200)
  343.         other.ammo_nails = 200;
  344.     if (other.ammo_rockets > 100)
  345.         other.ammo_rockets = 100;        
  346.     if (other.ammo_cells > 100)
  347.         other.ammo_cells = 100;        
  348. };
  349.  
  350.  
  351. float(float w) RankForWeapon =
  352. {
  353.     if (w == IT_LIGHTNING)
  354.         return 1;
  355.     if (w == IT_ROCKET_LAUNCHER)
  356.         return 2;
  357.     if (w == IT_SUPER_NAILGUN)
  358.         return 3;
  359.     if (w == IT_GRENADE_LAUNCHER)
  360.         return 4;
  361.     if (w == IT_SUPER_SHOTGUN)
  362.         return 5;
  363.     if (w == IT_NAILGUN)
  364.         return 6;
  365.     return 7;
  366. };
  367.  
  368. /*
  369. =============
  370. Deathmatch_Weapon
  371.  
  372. Deathmatch weapon change rules for picking up a weapon
  373.  
  374. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  375. =============
  376. */
  377. void(float old, float new) Deathmatch_Weapon =
  378. {
  379.     local float or, nr;
  380.  
  381. // change self.weapon if desired
  382.     or = RankForWeapon (self.weapon);
  383.     nr = RankForWeapon (new);
  384.     if ( nr < or )
  385.         self.weapon = new;
  386. };
  387.  
  388. /*
  389. =============
  390. weapon_touch
  391. =============
  392. */
  393. float() W_BestWeapon;
  394.  
  395. void() weapon_touch =
  396. {
  397.     local    float    hadammo, best, new, old;
  398.     local    entity    stemp;
  399.     local    float    leave;
  400.  
  401.     if (!(other.flags & FL_CLIENT))
  402.         return;
  403.  
  404. // if the player was using his best weapon, change up to the new one if better        
  405.     stemp = self;
  406.     self = other;
  407.     best = W_BestWeapon();
  408.     self = stemp;
  409.  
  410.     if (deathmatch == 2 || coop)
  411.         leave = 1;
  412.     else
  413.         leave = 0;
  414.     
  415.     if (self.classname == "weapon_nailgun")
  416.     {
  417.         if (leave && (other.items & IT_NAILGUN) )
  418.             return;
  419.         hadammo = other.ammo_nails;            
  420.         new = IT_NAILGUN;
  421.         other.ammo_nails = other.ammo_nails + 30;
  422.     }
  423.     else if (self.classname == "weapon_supernailgun")
  424.     {
  425.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  426.             return;
  427.         hadammo = other.ammo_rockets;            
  428.         new = IT_SUPER_NAILGUN;
  429.         other.ammo_nails = other.ammo_nails + 30;
  430.     }
  431.     else if (self.classname == "weapon_supershotgun")
  432.     {
  433.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  434.             return;
  435.         hadammo = other.ammo_rockets;            
  436.         new = IT_SUPER_SHOTGUN;
  437.         other.ammo_shells = other.ammo_shells + 5;
  438.     }
  439.     else if (self.classname == "weapon_rocketlauncher")
  440.     {
  441.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  442.             return;
  443.         hadammo = other.ammo_rockets;            
  444.         new = IT_ROCKET_LAUNCHER;
  445.         other.ammo_rockets = other.ammo_rockets + 5;
  446.     }
  447.     else if (self.classname == "weapon_grenadelauncher")
  448.     {
  449.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  450.             return;
  451.         hadammo = other.ammo_rockets;            
  452.         new = IT_GRENADE_LAUNCHER;
  453.         other.ammo_rockets = other.ammo_rockets + 5;
  454.     }
  455.     else if (self.classname == "weapon_lightning")
  456.     {
  457.         if (leave && (other.items & IT_LIGHTNING) )
  458.             return;
  459.         hadammo = other.ammo_rockets;            
  460.         new = IT_LIGHTNING;
  461.         other.ammo_cells = other.ammo_cells + 15;
  462.     }
  463.     else
  464.         objerror ("weapon_touch: unknown classname");
  465.  
  466.     sprint (other, "You got the ");
  467.     sprint (other, self.netname);
  468.         if (new == IT_NAILGUN)                     //kb
  469.          {
  470.           sprint(other,"/dartgun");
  471.           other.items = other.items | IT_DARTGUN ;
  472.          }
  473.         sprint (other, "\n");
  474. // weapon touch sound
  475.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  476.     stuffcmd (other, "bf\n");
  477.  
  478.     bound_other_ammo ();
  479.  
  480. // change to the weapon
  481.     old = other.items;
  482.     other.items = other.items | new;
  483.     
  484.     stemp = self;
  485.     self = other;
  486.  
  487.     if (!deathmatch)
  488.         self.weapon = new;
  489.     else
  490.         Deathmatch_Weapon (old, new);
  491.  
  492.     W_SetCurrentAmmo();
  493.  
  494.     self = stemp;
  495.  
  496.     if (leave)
  497.         return;
  498.  
  499. // remove it in single player, or setup for respawning in deathmatch
  500.     self.model = string_null;
  501.     self.solid = SOLID_NOT;
  502.     if (deathmatch == 1)
  503.         self.nextthink = time + 30;
  504.     self.think = SUB_regen;
  505.     
  506.     activator = other;
  507.     SUB_UseTargets();                // fire all targets / killtargets
  508. };
  509.  
  510.  
  511. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  512. */
  513.  
  514. void() weapon_supershotgun =
  515. {
  516.     precache_model ("progs/g_shot.mdl");
  517.     setmodel (self, "progs/g_shot.mdl");
  518.     self.weapon = IT_SUPER_SHOTGUN;
  519.     self.netname = "Double-barrelled Shotgun";
  520.     self.touch = weapon_touch;
  521.     setsize (self, '-16 -16 0', '16 16 56');
  522.     StartItem ();
  523. };
  524.  
  525. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  526. */
  527.  
  528. void() weapon_nailgun =
  529. {
  530.     precache_model ("progs/g_nail.mdl");
  531.     setmodel (self, "progs/g_nail.mdl");
  532.     self.weapon = IT_NAILGUN;
  533.     self.netname = "nailgun";
  534.     self.touch = weapon_touch;
  535.     setsize (self, '-16 -16 0', '16 16 56');
  536.     StartItem ();
  537. };
  538.  
  539. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  540. */
  541.  
  542. void() weapon_supernailgun =
  543. {
  544.     precache_model ("progs/g_nail2.mdl");
  545.     setmodel (self, "progs/g_nail2.mdl");
  546.     self.weapon = IT_SUPER_NAILGUN;
  547.     self.netname = "Super Nailgun";
  548.     self.touch = weapon_touch;
  549.     setsize (self, '-16 -16 0', '16 16 56');
  550.     StartItem ();
  551. };
  552.  
  553. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  554. */
  555.  
  556. void() weapon_grenadelauncher =
  557. {
  558.     precache_model ("progs/g_rock.mdl");
  559.     setmodel (self, "progs/g_rock.mdl");
  560.     self.weapon = 3;
  561.     self.netname = "Grenade Launcher";
  562.     self.touch = weapon_touch;
  563.     setsize (self, '-16 -16 0', '16 16 56');
  564.     StartItem ();
  565. };
  566.  
  567. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  568. */
  569.  
  570. void() weapon_rocketlauncher =
  571. {
  572.     precache_model ("progs/g_rock2.mdl");
  573.     setmodel (self, "progs/g_rock2.mdl");
  574.     self.weapon = 3;
  575.     self.netname = "Rocket Launcher";
  576.     self.touch = weapon_touch;
  577.     setsize (self, '-16 -16 0', '16 16 56');
  578.     StartItem ();
  579. };
  580.  
  581.  
  582. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  583. */
  584.  
  585. void() weapon_lightning =
  586. {
  587.     precache_model ("progs/g_light.mdl");
  588.     setmodel (self, "progs/g_light.mdl");
  589.     self.weapon = 3;
  590.     self.netname = "Thunderbolt";
  591.     self.touch = weapon_touch;
  592.     setsize (self, '-16 -16 0', '16 16 56');
  593.     StartItem ();
  594. };
  595.  
  596.  
  597. /*
  598. ===============================================================================
  599.  
  600. AMMO
  601.  
  602. ===============================================================================
  603. */
  604.  
  605. void() ammo_touch =
  606. {
  607. local entity    stemp;
  608. local float        best;
  609.  
  610.     if (other.classname != "player")
  611.         return;
  612.     if (other.health <= 0)
  613.         return;
  614.  
  615. // if the player was using his best weapon, change up to the new one if better        
  616.     stemp = self;
  617.     self = other;
  618.     best = W_BestWeapon();
  619.     self = stemp;
  620.  
  621.  
  622. // shotgun
  623.     if (self.weapon == 1)
  624.     {
  625.         if (other.ammo_shells >= 100)
  626.             return;
  627.         other.ammo_shells = other.ammo_shells + self.aflag;
  628.     }
  629.  
  630. // spikes
  631.     if (self.weapon == 2)
  632.     {
  633.         if (other.ammo_nails >= 200)
  634.             return;
  635.         other.ammo_nails = other.ammo_nails + self.aflag;
  636.     }
  637.  
  638. //    rockets
  639.     if (self.weapon == 3)
  640.     {
  641.         if (other.ammo_rockets >= 100)
  642.             return;
  643.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  644.     }
  645.  
  646. //    cells
  647.     if (self.weapon == 4)
  648.     {
  649.         if (other.ammo_cells >= 200)
  650.             return;
  651.         other.ammo_cells = other.ammo_cells + self.aflag;
  652.     }
  653.  
  654.     bound_other_ammo ();
  655.     
  656.     sprint (other, "You got the ");
  657.     sprint (other, self.netname);
  658.     sprint (other, "\n");
  659. // ammo touch sound
  660.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  661.     stuffcmd (other, "bf\n");
  662.  
  663. // change to a better weapon if appropriate
  664.  
  665.     if ( other.weapon == best )
  666.     {
  667.         stemp = self;
  668.         self = other;
  669.         self.weapon = W_BestWeapon();
  670.         W_SetCurrentAmmo ();
  671.         self = stemp;
  672.     }
  673.  
  674. // if changed current ammo, update it
  675.     stemp = self;
  676.     self = other;
  677.     W_SetCurrentAmmo();
  678.     self = stemp;
  679.  
  680. // remove it in single player, or setup for respawning in deathmatch
  681.     self.model = string_null;
  682.     self.solid = SOLID_NOT;
  683.     if (deathmatch == 1)
  684.         self.nextthink = time + 30;
  685.     
  686.     self.think = SUB_regen;
  687.  
  688.     activator = other;
  689.     SUB_UseTargets();                // fire all targets / killtargets
  690. };
  691.  
  692.  
  693.  
  694.  
  695. float WEAPON_BIG2 = 1;
  696.  
  697. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  698. */
  699.  
  700. void() item_shells =
  701. {
  702.     self.touch = ammo_touch;
  703.  
  704.     if (self.spawnflags & WEAPON_BIG2)
  705.     {
  706.         precache_model ("maps/b_shell1.bsp");
  707.         setmodel (self, "maps/b_shell1.bsp");
  708.         self.aflag = 40;
  709.     }
  710.     else
  711.     {
  712.         precache_model ("maps/b_shell0.bsp");
  713.         setmodel (self, "maps/b_shell0.bsp");
  714.         self.aflag = 20;
  715.     }
  716.     self.weapon = 1;
  717.     self.netname = "shells";
  718.     setsize (self, '0 0 0', '32 32 56');
  719.     StartItem ();
  720. };
  721.  
  722. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  723. */
  724.  
  725. void() item_spikes =
  726. {
  727.     self.touch = ammo_touch;
  728.  
  729.     if (self.spawnflags & WEAPON_BIG2)
  730.     {
  731.         precache_model ("maps/b_nail1.bsp");
  732.         setmodel (self, "maps/b_nail1.bsp");
  733.         self.aflag = 50;
  734.     }
  735.     else
  736.     {
  737.         precache_model ("maps/b_nail0.bsp");
  738.         setmodel (self, "maps/b_nail0.bsp");
  739.         self.aflag = 25;
  740.     }
  741.     self.weapon = 2;
  742.     self.netname = "nails";
  743.     setsize (self, '0 0 0', '32 32 56');
  744.     StartItem ();
  745. };
  746.  
  747. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  748. */
  749.  
  750. void() item_rockets =
  751. {
  752.     self.touch = ammo_touch;
  753.  
  754.     if (self.spawnflags & WEAPON_BIG2)
  755.     {
  756.         precache_model ("maps/b_rock1.bsp");
  757.         setmodel (self, "maps/b_rock1.bsp");
  758.         self.aflag = 10;
  759.     }
  760.     else
  761.     {
  762.         precache_model ("maps/b_rock0.bsp");
  763.         setmodel (self, "maps/b_rock0.bsp");
  764.         self.aflag = 5;
  765.     }
  766.     self.weapon = 3;
  767.     self.netname = "rockets";
  768.     setsize (self, '0 0 0', '32 32 56');
  769.     StartItem ();
  770. };
  771.  
  772.  
  773. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  774. */
  775.  
  776. void() item_cells =
  777. {
  778.     self.touch = ammo_touch;
  779.  
  780.     if (self.spawnflags & WEAPON_BIG2)
  781.     {
  782.         precache_model ("maps/b_batt1.bsp");
  783.         setmodel (self, "maps/b_batt1.bsp");
  784.         self.aflag = 12;
  785.     }
  786.     else
  787.     {
  788.         precache_model ("maps/b_batt0.bsp");
  789.         setmodel (self, "maps/b_batt0.bsp");
  790.         self.aflag = 6;
  791.     }
  792.     self.weapon = 4;
  793.     self.netname = "cells";
  794.     setsize (self, '0 0 0', '32 32 56');
  795.     StartItem ();
  796. };
  797.  
  798.  
  799. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  800. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  801. */
  802.  
  803. float WEAPON_SHOTGUN = 1;
  804. float WEAPON_ROCKET = 2;
  805. float WEAPON_SPIKES = 4;
  806. float WEAPON_BIG = 8;
  807. void() item_weapon =
  808. {
  809.     self.touch = ammo_touch;
  810.  
  811.     if (self.spawnflags & WEAPON_SHOTGUN)
  812.     {
  813.         if (self.spawnflags & WEAPON_BIG)
  814.         {
  815.             precache_model ("maps/b_shell1.bsp");
  816.             setmodel (self, "maps/b_shell1.bsp");
  817.             self.aflag = 40;
  818.         }
  819.         else
  820.         {
  821.             precache_model ("maps/b_shell0.bsp");
  822.             setmodel (self, "maps/b_shell0.bsp");
  823.             self.aflag = 20;
  824.         }
  825.         self.weapon = 1;
  826.         self.netname = "shells";
  827.     }
  828.  
  829.     if (self.spawnflags & WEAPON_SPIKES)
  830.     {
  831.         if (self.spawnflags & WEAPON_BIG)
  832.         {
  833.             precache_model ("maps/b_nail1.bsp");
  834.             setmodel (self, "maps/b_nail1.bsp");
  835.             self.aflag = 40;
  836.         }
  837.         else
  838.         {
  839.             precache_model ("maps/b_nail0.bsp");
  840.             setmodel (self, "maps/b_nail0.bsp");
  841.             self.aflag = 20;
  842.         }
  843.         self.weapon = 2;
  844.         self.netname = "spikes";
  845.     }
  846.  
  847.     if (self.spawnflags & WEAPON_ROCKET)
  848.     {
  849.         if (self.spawnflags & WEAPON_BIG)
  850.         {
  851.             precache_model ("maps/b_rock1.bsp");
  852.             setmodel (self, "maps/b_rock1.bsp");
  853.             self.aflag = 10;
  854.         }
  855.         else
  856.         {
  857.             precache_model ("maps/b_rock0.bsp");
  858.             setmodel (self, "maps/b_rock0.bsp");
  859.             self.aflag = 5;
  860.         }
  861.         self.weapon = 3;
  862.         self.netname = "rockets";
  863.     }
  864.     
  865.     setsize (self, '0 0 0', '32 32 56');
  866.     StartItem ();
  867. };
  868.  
  869.  
  870. /*
  871. ===============================================================================
  872.  
  873. KEYS
  874.  
  875. ===============================================================================
  876. */
  877.  
  878. void() key_touch =
  879. {
  880. local entity    stemp;
  881. local float        best;
  882.  
  883.     if (other.classname != "player")
  884.         return;
  885.     if (other.health <= 0)
  886.         return;
  887.     if (other.items & self.items)
  888.         return;
  889.  
  890.     sprint (other, "You got the ");
  891.     sprint (other, self.netname);
  892.     sprint (other,"\n");
  893.  
  894.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  895.     stuffcmd (other, "bf\n");
  896.     other.items = other.items | self.items;
  897.  
  898.     if (!coop)
  899.     {    
  900.         self.solid = SOLID_NOT;
  901.         self.model = string_null;
  902.     }
  903.  
  904.     activator = other;
  905.     SUB_UseTargets();                // fire all targets / killtargets
  906. };
  907.  
  908.  
  909. void() key_setsounds =
  910. {
  911.     if (world.worldtype == 0)
  912.     {
  913.         precache_sound ("misc/medkey.wav");
  914.         self.noise = "misc/medkey.wav";
  915.     }
  916.     if (world.worldtype == 1)
  917.     {
  918.         precache_sound ("misc/runekey.wav");
  919.         self.noise = "misc/runekey.wav";
  920.     }
  921.     if (world.worldtype == 2)
  922.     {
  923.         precache_sound2 ("misc/basekey.wav");
  924.         self.noise = "misc/basekey.wav";
  925.     }
  926. };
  927.  
  928. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  929. SILVER key
  930. In order for keys to work
  931. you MUST set your maps
  932. worldtype to one of the
  933. following:
  934. 0: medieval
  935. 1: metal
  936. 2: base
  937. */
  938.  
  939. void() item_key1 =
  940. {
  941.     if (world.worldtype == 0)
  942.     {
  943.         precache_model ("progs/w_s_key.mdl");
  944.         setmodel (self, "progs/w_s_key.mdl");
  945.         self.netname = "silver key";
  946.     }
  947.     else if (world.worldtype == 1)
  948.     {
  949.         precache_model ("progs/m_s_key.mdl");
  950.         setmodel (self, "progs/m_s_key.mdl");
  951.         self.netname = "silver runekey";
  952.     }
  953.     else if (world.worldtype == 2)
  954.     {
  955.         precache_model2 ("progs/b_s_key.mdl");
  956.         setmodel (self, "progs/b_s_key.mdl");
  957.         self.netname = "silver keycard";
  958.     }
  959.     key_setsounds();
  960.     self.touch = key_touch;
  961.     self.items = IT_KEY1;
  962.     setsize (self, '-16 -16 -24', '16 16 32');
  963.     StartItem ();
  964. };
  965.  
  966. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  967. GOLD key
  968. In order for keys to work
  969. you MUST set your maps
  970. worldtype to one of the
  971. following:
  972. 0: medieval
  973. 1: metal
  974. 2: base
  975. */
  976.  
  977. void() item_key2 =
  978. {
  979.     if (world.worldtype == 0)
  980.     {
  981.         precache_model ("progs/w_g_key.mdl");
  982.         setmodel (self, "progs/w_g_key.mdl");
  983.         self.netname = "gold key";
  984.     }
  985.     if (world.worldtype == 1)
  986.     {
  987.         precache_model ("progs/m_g_key.mdl");
  988.         setmodel (self, "progs/m_g_key.mdl");
  989.         self.netname = "gold runekey";
  990.     }
  991.     if (world.worldtype == 2)
  992.     {
  993.         precache_model2 ("progs/b_g_key.mdl");
  994.         setmodel (self, "progs/b_g_key.mdl");
  995.         self.netname = "gold keycard";
  996.     }
  997.     key_setsounds();
  998.     self.touch = key_touch;
  999.     self.items = IT_KEY2;
  1000.     setsize (self, '-16 -16 -24', '16 16 32');
  1001.     StartItem ();
  1002. };
  1003.  
  1004.  
  1005.  
  1006. /*
  1007. ===============================================================================
  1008.  
  1009. END OF LEVEL RUNES
  1010.  
  1011. ===============================================================================
  1012. */
  1013.  
  1014. void() sigil_touch =
  1015. {
  1016. local entity    stemp;
  1017. local float        best;
  1018.  
  1019.     if (other.classname != "player")
  1020.         return;
  1021.     if (other.health <= 0)
  1022.         return;
  1023.  
  1024.     centerprint (other, "You got the rune!");
  1025.  
  1026.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1027.     stuffcmd (other, "bf\n");
  1028.     self.solid = SOLID_NOT;
  1029.     self.model = string_null;
  1030.     serverflags = serverflags | (self.spawnflags & 15);
  1031.     self.classname = "";        // so rune doors won't find it
  1032.     
  1033.     activator = other;
  1034.     SUB_UseTargets();                // fire all targets / killtargets
  1035. };
  1036.  
  1037.  
  1038. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1039. End of level sigil, pick up to end episode and return to jrstart.
  1040. */
  1041.  
  1042. void() item_sigil =
  1043. {
  1044.     if (!self.spawnflags)
  1045.         objerror ("no spawnflags");
  1046.  
  1047.     precache_sound ("misc/runekey.wav");
  1048.     self.noise = "misc/runekey.wav";
  1049.  
  1050.     if (self.spawnflags & 1)
  1051.     {
  1052.         precache_model ("progs/end1.mdl");
  1053.         setmodel (self, "progs/end1.mdl");
  1054.     }
  1055.     if (self.spawnflags & 2)
  1056.     {
  1057.         precache_model2 ("progs/end2.mdl");
  1058.         setmodel (self, "progs/end2.mdl");
  1059.     }
  1060.     if (self.spawnflags & 4)
  1061.     {
  1062.         precache_model2 ("progs/end3.mdl");
  1063.         setmodel (self, "progs/end3.mdl");
  1064.     }
  1065.     if (self.spawnflags & 8)
  1066.     {
  1067.         precache_model2 ("progs/end4.mdl");
  1068.         setmodel (self, "progs/end4.mdl");
  1069.     }
  1070.     
  1071.     self.touch = sigil_touch;
  1072.     setsize (self, '-16 -16 -24', '16 16 32');
  1073.     StartItem ();
  1074. };
  1075.  
  1076. /*
  1077. ===============================================================================
  1078.  
  1079. POWERUPS
  1080.  
  1081. ===============================================================================
  1082. */
  1083.  
  1084. void() powerup_touch;
  1085.  
  1086.  
  1087. void() powerup_touch =
  1088. {
  1089. local entity    stemp;
  1090. local float        best;
  1091.  
  1092.     if (other.classname != "player")
  1093.         return;
  1094.     if (other.health <= 0)
  1095.         return;
  1096.  
  1097.     sprint (other, "You got the ");
  1098.     sprint (other, self.netname);
  1099.     sprint (other,"\n");
  1100.  
  1101.     if (deathmatch)
  1102.     {
  1103.         self.mdl = self.model;
  1104.         
  1105.         if ((self.classname == "item_artifact_invulnerability") ||
  1106.             (self.classname == "item_artifact_invisibility"))
  1107.             self.nextthink = time + 60*5;
  1108.         else
  1109.             self.nextthink = time + 60;
  1110.         
  1111.         self.think = SUB_regen;
  1112.     }    
  1113.  
  1114.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1115.     stuffcmd (other, "bf\n");
  1116.     self.solid = SOLID_NOT;
  1117.     other.items = other.items | self.items;
  1118.     self.model = string_null;
  1119.  
  1120. // do the apropriate action
  1121.     if (self.classname == "item_artifact_envirosuit")
  1122.     {
  1123.         other.rad_time = 1;
  1124.         other.radsuit_finished = time + 30;
  1125.     }
  1126.     
  1127.     if (self.classname == "item_artifact_invulnerability")
  1128.     {
  1129.         other.invincible_time = 1;
  1130.         other.invincible_finished = time + 30;
  1131.     }
  1132.     
  1133.     if (self.classname == "item_artifact_invisibility")
  1134.     {
  1135.         other.invisible_time = 1;
  1136.         other.invisible_finished = time + 30;
  1137.     }
  1138.  
  1139.     if (self.classname == "item_artifact_super_damage")
  1140.     {
  1141.         other.super_time = 1;
  1142.         other.super_damage_finished = time + 30;
  1143.     }    
  1144.  
  1145.     activator = other;
  1146.     SUB_UseTargets();                // fire all targets / killtargets
  1147. };
  1148.  
  1149.  
  1150.  
  1151. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1152. Player is invulnerable for 30 seconds
  1153. */
  1154. void() item_artifact_invulnerability =
  1155. {
  1156.     self.touch = powerup_touch;
  1157.  
  1158.     precache_model ("progs/invulner.mdl");
  1159.     precache_sound ("items/protect.wav");
  1160.     precache_sound ("items/protect2.wav");
  1161.     precache_sound ("items/protect3.wav");
  1162.     self.noise = "items/protect.wav";
  1163.     setmodel (self, "progs/invulner.mdl");
  1164.     self.netname = "Pentagram of Protection";
  1165.     self.items = IT_INVULNERABILITY;
  1166.     setsize (self, '-16 -16 -24', '16 16 32');
  1167.     StartItem ();
  1168. };
  1169.  
  1170. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1171. Player takes no damage from water or slime for 30 seconds
  1172. */
  1173. void() item_artifact_envirosuit =
  1174. {
  1175.     self.touch = powerup_touch;
  1176.  
  1177.     precache_model ("progs/suit.mdl");
  1178.     precache_sound ("items/suit.wav");
  1179.     precache_sound ("items/suit2.wav");
  1180.     self.noise = "items/suit.wav";
  1181.     setmodel (self, "progs/suit.mdl");
  1182.     self.netname = "Biosuit";
  1183.     self.items = IT_SUIT;
  1184.     setsize (self, '-16 -16 -24', '16 16 32');
  1185.     StartItem ();
  1186. };
  1187.  
  1188.  
  1189. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1190. Player is invisible for 30 seconds
  1191. */
  1192. void() item_artifact_invisibility =
  1193. {
  1194.     self.touch = powerup_touch;
  1195.  
  1196.     precache_model ("progs/invisibl.mdl");
  1197.     precache_sound ("items/inv1.wav");
  1198.     precache_sound ("items/inv2.wav");
  1199.     precache_sound ("items/inv3.wav");
  1200.     self.noise = "items/inv1.wav";
  1201.     setmodel (self, "progs/invisibl.mdl");
  1202.     self.netname = "Ring of Shadows";
  1203.     self.items = IT_INVISIBILITY;
  1204.     setsize (self, '-16 -16 -24', '16 16 32');
  1205.     StartItem ();
  1206. };
  1207.  
  1208.  
  1209. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1210. The next attack from the player will do 4x damage
  1211. */
  1212. void() item_artifact_super_damage =
  1213. {
  1214.     self.touch = powerup_touch;
  1215.  
  1216.     precache_model ("progs/quaddama.mdl");
  1217.     precache_sound ("items/damage.wav");
  1218.     precache_sound ("items/damage2.wav");
  1219.     precache_sound ("items/damage3.wav");
  1220.     self.noise = "items/damage.wav";
  1221.     setmodel (self, "progs/quaddama.mdl");
  1222.     self.netname = "Quad Damage";
  1223.     self.items = IT_QUAD;
  1224.     setsize (self, '-16 -16 -24', '16 16 32');
  1225.     StartItem ();
  1226. };
  1227.  
  1228.  
  1229.  
  1230. /*
  1231. ===============================================================================
  1232.  
  1233. PLAYER BACKPACKS
  1234.  
  1235. ===============================================================================
  1236. */
  1237.  
  1238. void() BackpackTouch =
  1239. {
  1240.     local string    s;
  1241.     local    float    best;
  1242.     local        entity    stemp;
  1243.     
  1244.     if (other.classname != "player")
  1245.         return;
  1246.     if (other.health <= 0)
  1247.         return;
  1248.         
  1249. // if the player was using his best weapon, change up to the new one if better        
  1250.     stemp = self;
  1251.     self = other;
  1252.     best = W_BestWeapon();
  1253.     self = stemp;
  1254.  
  1255. // change weapons
  1256.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1257.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1258.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1259.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1260.  
  1261.     other.items = other.items | self.items;
  1262.     
  1263.     bound_other_ammo ();
  1264.  
  1265.     sprint (other, "You get ");
  1266.  
  1267.     if (self.ammo_shells)
  1268.     {
  1269.         s = ftos(self.ammo_shells);
  1270.         sprint (other, s);
  1271.         sprint (other, " shells  ");
  1272.     }
  1273.     if (self.ammo_nails)
  1274.     {
  1275.         s = ftos(self.ammo_nails);
  1276.         sprint (other, s);
  1277.         sprint (other, " nails ");
  1278.     }
  1279.     if (self.ammo_rockets)
  1280.     {
  1281.         s = ftos(self.ammo_rockets);
  1282.         sprint (other, s);
  1283.         sprint (other, " rockets  ");
  1284.     }
  1285.     if (self.ammo_cells)
  1286.     {
  1287.         s = ftos(self.ammo_cells);
  1288.         sprint (other, s);
  1289.         sprint (other, " cells  ");
  1290.     }
  1291.     
  1292.     sprint (other, "\n");
  1293. // backpack touch sound
  1294.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1295.     stuffcmd (other, "bf\n");
  1296.  
  1297. // change to a better weapon if appropriate
  1298.     if ( other.weapon == best )
  1299.     {
  1300.         stemp = self;
  1301.         self = other;
  1302.         self.weapon = W_BestWeapon();
  1303.         self = stemp;
  1304.     }
  1305.  
  1306.     
  1307.     remove(self);
  1308.     
  1309.     self = other;
  1310.     W_SetCurrentAmmo ();
  1311. };
  1312.  
  1313. /*
  1314. ===============
  1315. DropBackpack
  1316. ===============
  1317. */
  1318. void() DropBackpack =
  1319. {
  1320.     local entity    item;
  1321.  
  1322.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1323.         return;    // nothing in it
  1324.  
  1325.     item = spawn();
  1326.     item.origin = self.origin - '0 0 24';
  1327.     
  1328.     item.items = self.weapon;
  1329.  
  1330.     item.ammo_shells = self.ammo_shells;
  1331.     item.ammo_nails = self.ammo_nails;
  1332.     item.ammo_rockets = self.ammo_rockets;
  1333.     item.ammo_cells = self.ammo_cells;
  1334.  
  1335.     item.velocity_z = 300;
  1336.     item.velocity_x = -100 + (random() * 200);
  1337.     item.velocity_y = -100 + (random() * 200);
  1338.     
  1339.     item.flags = FL_ITEM;
  1340.     item.solid = SOLID_TRIGGER;
  1341.     item.movetype = MOVETYPE_TOSS;
  1342.     setmodel (item, "progs/backpack.mdl");
  1343.     setsize (item, '-16 -16 0', '16 16 56');
  1344.     item.touch = BackpackTouch;
  1345.     
  1346.     item.nextthink = time + 120;    // remove after 2 minutes
  1347.     item.think = SUB_Remove;
  1348. };
  1349.